package com.dries.portal.module.coupon.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dries.portal.module.coupon.enums.CouponCategory;
import com.dries.portal.module.coupon.enums.CouponStatus;
import com.dries.common.exception.ApiException;
import com.dries.portal.module.coupon.entity.Coupon;
import com.dries.portal.module.coupon.entity.Template;
import com.dries.portal.module.coupon.form.AddTemplateForm;
import com.dries.portal.module.coupon.mapper.TemplateMapper;
import com.dries.portal.module.coupon.service.IAsyncService;
import com.dries.portal.module.coupon.service.ICouponService;
import com.dries.portal.module.coupon.service.ITemplateService;
import com.dries.portal.module.coupon.utils.convert.AddTemplateForm2TemplateConvert;
import com.dries.portal.module.coupon.utils.convert.Template2CouponTemplateSDKConvert;
import com.dries.portal.module.coupon.vo.CouponTemplateRecord;
import com.dries.portal.module.coupon.vo.CouponTemplateSDK;
import io.jsonwebtoken.lang.Collections;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TemplateServiceImpl extends ServiceImpl<TemplateMapper, Template> implements ITemplateService {

    @Resource
    private IAsyncService asyncService;
    @Resource
    private ICouponService couponService;

    /**
     * 根据优惠券模板ID 获取优惠券模板信息
     *
     * @param id
     */
    @Override
    public Template getTemplateInfoById(Integer id) {
        Template template = baseMapper.selectOne(new QueryWrapper<Template>().lambda()
                .eq(Template::getId, id)
                .eq(Template::getIsDelete, 0)
        );
        return template;
    }

    /**
     * 查找所有可用的优惠券模板
     */
    @Override
    public List<CouponTemplateSDK> findAllUsableTemplate() {
        List<Template> list = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(Template::getAvailable, 1)
                .eq(Template::getExpired, 0)
                .eq(Template::getIsDelete, 0)
                .list();

        return list.stream().map(Template2CouponTemplateSDKConvert::convert).collect(Collectors.toList());
    }
    /**
     * 查找所有可用的抵扣优惠券模板
     */
    @Override
    public List<CouponTemplateSDK> findAllDeductionUsableTemplate() {

        List<Template> list = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(Template::getAvailable, 1)
                .eq(Template::getCategory, CouponCategory.DIKOU.getCode())
                .eq(Template::getExpired, 0)
                .eq(Template::getIsDelete, 0)
                .list();

        return list.stream().map(Template2CouponTemplateSDKConvert::convert).collect(Collectors.toList());

    }

    /**
     * 获取模板ids 到 CouponTemplateSDK 的映射
     *
     * @param ids
     */
    @Override
    public Map<Integer, CouponTemplateSDK> findIdsTemplateSDK(Collection<Integer> ids) {
        List<Template> list = new LambdaQueryChainWrapper<>(baseMapper)
                .in(Template::getId, ids)
                .eq(Template::getIsDelete, 0)
                .list();
        log.info("优惠券列表=====>{}",JSONUtil.toJsonStr(list));
        return list.stream().map(Template2CouponTemplateSDKConvert::convert).collect(Collectors.toMap(
                CouponTemplateSDK::getId, Function.identity()
        ));
    }

    /**
     * 创建优惠券模板
     *
     * @param form
     */
    @Override
    public Template buildTemplate(AddTemplateForm form) {

        List<Template> list = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(Template::getName, form.getName())
                .eq(Template::getIsDelete, 0)
                .list();
        // 判断是否有同名的优惠券模板
        if (!Collections.isEmpty(list)){
            throw new ApiException("优惠券模板名已存在");
        }

        // 构造Template 实体类
        Template convert = AddTemplateForm2TemplateConvert.convert(form);
        baseMapper.insert(convert);

        // 根据优惠券模板异步生成优惠券码
        asyncService.asyncConstructCouponByTemplate(convert);

        return convert;
    }

    /**
     * 根据模板名称查询模板
     *
     * @param name
     */
    @Override
    public Template findByName(String name) {
        List<Template> list = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(Template::getName, name)
                .eq(Template::getIsDelete, 0)
                .list();
        if (Collections.isEmpty(list) ) {
            throw new ApiException("优惠券模板名不存在");
        }
        return list.get(0);
    }

    /**
     * 根据available 和 expired标记查找模板记录
     *
     * @param available
     * @param expired
     */
    @Override
    public List<Template> findAllByAvailableAndExpired(Integer available, Integer expired) {
        List<Template> list = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(Template::getAvailable, available)
                .eq(Template::getExpired, expired)
                .eq(Template::getIsDelete, 0)
                .list();
        return list;
    }

    /**
     * 根据expired标记查找模板记录
     *
     * @param expired
     */
    @Override
    public List<Template> findAllExpired(Integer expired) {
        List<Template> list = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(Template::getExpired, expired)
                .eq(Template::getIsDelete, 0)
                .list();
        return list;
    }

    @Override
    public CouponTemplateRecord getTemplateRecordByShopId(String templateId) {

        Template template = baseMapper.selectOne(new QueryWrapper<Template>().lambda()
                .eq(Template::getId, templateId)
                .eq(Template::getIsDelete, 0)
        );

        if (template == null){
            throw new ApiException("该优惠券模板不存在");
        }

        List<Coupon> list = couponService.list();
        CouponTemplateRecord record = new CouponTemplateRecord();
        record.setId(template.getId());
        record.setTotalQuantity(template.getCouponCount());
        // 已使用的
        long userCount = list.stream().filter(c -> c.getTemplateId().equals(template.getId()) && c.getStatus().equals(CouponStatus.USED))
                .count();
        // 未使用的
        long unUserCount = list.stream().filter(c -> c.getTemplateId().equals(template.getId()) && c.getStatus().equals(CouponStatus.USABLE))
                .count();
        // 过期的
        long expiredCount = list.stream().filter(c -> c.getTemplateId().equals(template.getId()) && c.getStatus().equals(CouponStatus.EXPIRED))
                .count();

        record.setUsed((int) userCount);
        record.setUnUsed((int) unUserCount);
        record.setExpired((int) expiredCount);
        record.setReceiveAward((int) (userCount + unUserCount + expiredCount));

        return record;
    }


}